{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "2eea87ea-d5bb-4154-98b2-64f705925f1e",
   "metadata": {},
   "source": [
    "# 第六节、复制和视图"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "59f0c1bc-e9f5-4648-b0da-a0f24cc8432d",
   "metadata": {},
   "source": [
    "在操作数组时，有时会将其数据复制到新数组中，有时不复制。\n",
    "\n",
    "对于初学者来说，这通常会引起混乱，有以下三种情况："
   ]
  },
  {
   "cell_type": "markdown",
   "id": "49c4cba7-17cc-4ca2-856f-ae5a0ea21c22",
   "metadata": {},
   "source": [
    "## 完全没有复制"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "0287444c-be7b-43b4-b1ee-4723549206e6",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "113f59a3-d7e4-4176-b825-130f6a1d5c7f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[82, 49, 44, 69,  9],\n",
       "       [ 7, 84, 57, 78, 35],\n",
       "       [ 6, 93, 71, 32, 92],\n",
       "       [94, 87,  0, 79, 90]])"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = np.random.randint(0, 100, size=(4, 5))\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "67918035-25a4-4f4a-bd99-5aeee104f804",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 将a赋值给b\n",
    "b = a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "a6f0040e-fb7c-4171-82be-0bcefbdd2869",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a is b   # 看看他们是否指向同一块内存\n",
    "# True说明他们是同一个对象的不同引用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "cacaaffb-e8c5-4db5-a5c8-df3fcc535ba0",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 修改b中的元素，a中的元素也会跟着改变\n",
    "b[0, 0] = 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "9cc31add-1aa4-434a-84f1-f12276554a1a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0, 18, 47, 24, 50],\n",
       "       [17, 27, 76, 18, 83],\n",
       "       [65,  1, 69, 92, 80],\n",
       "       [ 3, 42, 91, 89, 18]])"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "753eb328-0fc5-4da0-9f23-0b03ac75123c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0, 18, 47, 24, 50],\n",
       "       [17, 27, 76, 18, 83],\n",
       "       [65,  1, 69, 92, 80],\n",
       "       [ 3, 42, 91, 89, 18]])"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "32c6d057-dbe2-46f4-8573-cd3577bb8939",
   "metadata": {},
   "source": [
    "## 查看或浅拷贝"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "84883ddf-431e-4393-aaa1-33d2af2bda9d",
   "metadata": {},
   "source": [
    "不同的数组对象可以共享相同的数据，该view方法会创建一个查看相同数据的新数组对象。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "9ba0663e-7f04-4fc8-be31-ba2040579834",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "f53f88da-3f27-4b06-a3aa-1bfcf9a931a8",
   "metadata": {},
   "outputs": [],
   "source": [
    "a = np.random.randint(0, 100, size=(4, 5))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "a3ae8719-6eec-4686-9f1b-d8f7768f5780",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[27, 18, 47, 24, 50],\n",
       "       [17, 27, 76, 18, 83],\n",
       "       [65,  1, 69, 92, 80],\n",
       "       [ 3, 42, 91, 89, 18]])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "b52fe0f3-4b0d-4be7-a859-41e73a37a81a",
   "metadata": {},
   "outputs": [],
   "source": [
    "b = a.view()   # 使用a中的数据创建一个新数组对象"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "69ba33e8-0ac8-4f8f-ac6e-a6970f5c82c2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a is b   # b是一个新对象是放在不同的内存地址里面的，但里面的数据依旧是浅拷贝"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "6d6c2225-cdfa-4a5a-89c1-169b5e8f0ca3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[27, 18, 47, 24, 50],\n",
       "       [17, 27, 76, 18, 83],\n",
       "       [65,  1, 69, 92, 80],\n",
       "       [ 3, 42, 91, 89, 18]])"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b  # 如果直接查看b，则看到的是b自己的数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "c3ec8a86-f982-47dd-93b5-61ce7cb55128",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[27, 18, 47, 24, 50],\n",
       "       [17, 27, 76, 18, 83],\n",
       "       [65,  1, 69, 92, 80],\n",
       "       [ 3, 42, 91, 89, 18]])"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b.base   # 如果调用base属性，则看到的是a的数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "f98bd9e8-70bb-4826-a39a-62b27cbc2f12",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b.base is a   # 返回True说明b视图的根数据和a一样"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "73b4bdc3-9ae3-492f-8f31-1befd8d72d22",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b.flags.owndata   # 返回False  b中的数据不是其自己的"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "e5eca784-c660-4fa5-bd1c-1e7a8d0dad52",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a.flags.owndata   # 返回True   a中的数据是其自己的"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "163d966a-7a9a-4882-a5fd-579f8726e3a8",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 修改b中数据，a中也发生改变\n",
    "b[0, 0] = 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "41d31508-fc67-4384-8fc0-b59a198f0f8e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0, 18, 47, 24, 50],\n",
       "       [17, 27, 76, 18, 83],\n",
       "       [65,  1, 69, 92, 80],\n",
       "       [ 3, 42, 91, 89, 18]])"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "473457d9-a868-422b-8042-f1bbb5f6cb5c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0, 18, 47, 24, 50],\n",
       "       [17, 27, 76, 18, 83],\n",
       "       [65,  1, 69, 92, 80],\n",
       "       [ 3, 42, 91, 89, 18]])"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "acf66683-8bd4-41ab-bcbe-d0e428173459",
   "metadata": {},
   "source": [
    "## 深拷贝"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c00e70ed-261a-4b98-8110-47925ccf5ab2",
   "metadata": {},
   "source": [
    "copy应该在不再需要原来的数组情况下，切片后调用。例如，假设a是一个巨大的中间结果。而最终结果b仅包含a的一小部分，则在b使用切片进行构造时应该制作一个深拷贝："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "9f9cc708-5f2b-412f-822c-eb1b1172a62b",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "f7a10717-229f-490b-9ec6-4fdce753dae9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0, 18, 47, 24, 50],\n",
       "       [17, 27, 76, 18, 83],\n",
       "       [65,  1, 69, 92, 80],\n",
       "       [ 3, 42, 91, 89, 18]])"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "092b2f9f-31d3-4c16-8dc4-bff20b863bf1",
   "metadata": {},
   "outputs": [],
   "source": [
    "b = a.copy()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "ab752bb5-552e-4ecc-8ccb-3f946f3ecedc",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0, 18, 47, 24, 50],\n",
       "       [17, 27, 76, 18, 83],\n",
       "       [65,  1, 69, 92, 80],\n",
       "       [ 3, 42, 91, 89, 18]])"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "d3a15495-14a2-4fc4-9101-3f821f45c705",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b is a  # 他们不是同一个对象"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "06697642-d393-480b-9246-3dc0729625b2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b.base is a  # b中的内容也不是引用的a，是b完完全全复制出来的"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "e72c42c0-42e9-4f24-af3a-49dcee057541",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b.flags.owndata   # b中的内容完全属于a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "7e7779f3-e199-48a0-b20d-390c3d4039a6",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 修改b中的内容，a也不会改变\n",
    "b[0, 0] = 999"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "61e156c3-8d80-4314-aca2-2b7c909f2a59",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[999,  18,  47,  24,  50],\n",
       "       [ 17,  27,  76,  18,  83],\n",
       "       [ 65,   1,  69,  92,  80],\n",
       "       [  3,  42,  91,  89,  18]])"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "d76e2934-09a2-478f-91b9-6dca47838d20",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0, 18, 47, 24, 50],\n",
       "       [17, 27, 76, 18, 83],\n",
       "       [65,  1, 69, 92, 80],\n",
       "       [ 3, 42, 91, 89, 18]])"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f021d5ff-7c26-41a0-88d2-a47e2f8b9f4f",
   "metadata": {},
   "source": [
    "如果a特别大，那么b可以是对a的切片的一个深拷贝"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "e7783b26-f604-468b-bed3-02b0c7cd1cf1",
   "metadata": {},
   "outputs": [],
   "source": [
    "large = np.arange(1e8)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "294fe03a-a161-4313-b290-82fb6277186f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "100000000"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "large.size"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "7c45e152-4e4a-4ff6-84ce-1fdae625f835",
   "metadata": {},
   "outputs": [],
   "source": [
    "b = large[::1000000].copy()   # b可以是对a的切片的一个深拷贝"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "ba60e6af-b31f-4f13-b5d8-da6ce8553bfe",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 然后再把a删掉，释放内存\n",
    "del a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "id": "36632b15-46b4-460b-8698-f5ac1456b11a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([       0.,  1000000.,  2000000.,  3000000.,  4000000.,  5000000.,\n",
       "        6000000.,  7000000.,  8000000.,  9000000., 10000000., 11000000.,\n",
       "       12000000., 13000000., 14000000., 15000000., 16000000., 17000000.,\n",
       "       18000000., 19000000., 20000000., 21000000., 22000000., 23000000.,\n",
       "       24000000., 25000000., 26000000., 27000000., 28000000., 29000000.,\n",
       "       30000000., 31000000., 32000000., 33000000., 34000000., 35000000.,\n",
       "       36000000., 37000000., 38000000., 39000000., 40000000., 41000000.,\n",
       "       42000000., 43000000., 44000000., 45000000., 46000000., 47000000.,\n",
       "       48000000., 49000000., 50000000., 51000000., 52000000., 53000000.,\n",
       "       54000000., 55000000., 56000000., 57000000., 58000000., 59000000.,\n",
       "       60000000., 61000000., 62000000., 63000000., 64000000., 65000000.,\n",
       "       66000000., 67000000., 68000000., 69000000., 70000000., 71000000.,\n",
       "       72000000., 73000000., 74000000., 75000000., 76000000., 77000000.,\n",
       "       78000000., 79000000., 80000000., 81000000., 82000000., 83000000.,\n",
       "       84000000., 85000000., 86000000., 87000000., 88000000., 89000000.,\n",
       "       90000000., 91000000., 92000000., 93000000., 94000000., 95000000.,\n",
       "       96000000., 97000000., 98000000., 99000000.])"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "c16f9172-ca84-4d3e-a8b4-8a7cb1aa4235",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "100"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b.size"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "144826ef-038c-4111-9aed-8b8167f9290b",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
